﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace game
{
    public class Line
    {
        const int RIGHT = 8;
        const int TOP = 4;
        const int LEFT = 2;
        const int BOTTOM = 1;

        static float xMin = -1.0f;
        static float yMin = -1.0f;
        static float xMax = 1.0f;
        static float yMax = 1.0f;

        private static int GetClipCode(float x, float y)
        {
            int code = 0;
            if (y > yMax)
                code |= TOP;
            else if (y < yMin)
                code |= BOTTOM;
            if (x > xMax)
                code |= RIGHT;
            else if (x < xMin)
                code |= LEFT;
            return code;
        }

        public static bool Clip(ref float x1, ref float y1, ref float x2, ref float y2)
        {
            int code1, code2, codeOut;
            bool done = false;

            code1 = GetClipCode(x1, y1);
            code2 = GetClipCode(x2, y2);


            do
            {
                if ((code1 | code2) == 0)
                {
                    done = true;
                }
                else if ((code1 & code2) != 0)
                {
                    done = true;
                    return true;
                }

                else
                {
                    float x=0, y=0;

                    codeOut = (code1 != 0) ? code1 : code2;

                    if ((codeOut & TOP) != 0)
                    {
                        x = x1 + (x2 - x1) * (yMax - y1) / (y2 - y1);
                        y = yMax;
                    }
                    else if ((codeOut & BOTTOM) != 0)  //point is below the clip rectangle
                    {
                        x = x1 + (x2 - x1) * (yMin - y1) / (y2 - y1);
                        y = yMin;
                    }
                    else if ((codeOut & RIGHT) != 0)   //point is to the right of clip rectangle
                    {
                        y = y1 + (y2 - y1) * (xMax - x1) / (x2 - x1);
                        x = xMax;
                    }
                    else if ((codeOut & LEFT) != 0)                         //point is to the left of clip rectangle
                    {
                        y = y1 + (y2 - y1) * (xMin - x1) / (x2 - x1);
                        x = xMin;
                    }
                    //Now we move outside point to intersection point to clip
                    //and get ready for next pass.
                    if (codeOut == code1)
                    {
                        x1 = x;
                        y1 = y;
                        code1 = GetClipCode(x1, y1);
                    }
                    else
                    {
                        x2 = x;
                        y2 = y;
                        code2 = GetClipCode(x2, y2);
                    }
                }
            } while (!done);

            return false;
        }
    }
}
